package sys.knot.model;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

public class ResultConsumer {
    private static final String APPLICATION_JSON = "application/json";

    private OutputStream outputStream;
    private List<String> errors = new ArrayList<>();
    private List<String> warnings = new ArrayList<>();
    private boolean firstResult = true;

    public ResultConsumer(HttpServletResponse response) throws IOException {
        this.outputStream = response.getOutputStream();

        response.setContentType(APPLICATION_JSON);
        //start object and result array
        outputStream.write("{\n\t\"result\": [\n".getBytes());
    }
    public void consume(ResultPart resultPart) throws IOException {
        if (firstResult) {
            firstResult = false;
        } else {
            write(",\n");
        }
        writeMapAsJson(resultPart);
        //flush(); //TODO set buffersize or do this at configured times.
    }
    public void close() throws IOException {
        //close result array
        write("\n\t]");

        if (warnings.size() > 0) {
            //start warnings array
            write(",\n\t\"warnings\": [\n");

            boolean firstWarning = true;
            for (String warning : warnings) {
                if (firstWarning) {
                    firstWarning = false;
                } else {
                    write(",\n");
                }

                write("\t\t\"");
                write(warning);
                write("\"");
            }

            //close warnings array
            write("\n\t]");
        }

        if (errors.size() > 0) {
            //start warnings array
            write(",\n\t\"errors\": [\n");

            boolean firstWarning = true;
            for (String error : errors) {
                if (firstWarning) {
                    firstWarning = false;
                } else {
                    write(",\n");
                }

                write("\t\t\"");
                write(error);
                write("\"");
            }

            //close warnings array
            write("\n\t]");
        }

        //close json object
        write("\n}");

        outputStream.close();
    }

    public void addWarning(String warning) {
        warnings.add(warning);
    }

    private void writeMapAsJson(ResultPart resultPart) throws IOException {
        write("\t\t{\n");
        boolean first = true;
        for (String key : resultPart.keySet()) {
            if (first) {
                first = false;
            } else {
                write(",\n");
            }
            write("\t\t\t\"");
            write(key);
            write("\": \"");
            write(resultPart.get(key).toString());
            write("\"");
        }
        write("\n\t\t}");
    }

    private void write(String s) throws IOException {
        outputStream.write(s.getBytes());
    }

    public void addError(String error) {
        errors.add(error);
    }
}
